﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using DataBaseBST;
using System.Runtime.Serialization.Formatters.Binary;

namespace Application
{
    public class TableManager
    {
        private string baseDirectoryPath = "";
        public TableManager(string dbDirectoryPath) { baseDirectoryPath = dbDirectoryPath; }

        public TableManager() { }

        public bool CreateTablesDirectories(string dbDirectoryName, string tableName)
        {
            baseDirectoryPath = dbDirectoryName;
            if (!Directory.Exists(string.Format("{0}{1}/", baseDirectoryPath, "tables")))
            {
                Directory.CreateDirectory(string.Format("{0}{1}/", baseDirectoryPath, "tables"));
                BST<string, object> table = new BST<string, object>();
                FlushTable<string, object>(string.Format("{0}{1}/{2}.treedb", baseDirectoryPath, "tables", tableName), table);
            }
            else
            {
                BST<string, object> table = new BST<string, object>();
                FlushTable<string, object>(string.Format("{0}{1}/{2}.treedb", baseDirectoryPath, "tables", tableName), table);
            }

            return false;

        }

        public bool DropDatabasesDirectories(string tbName)
        {
            if (!Directory.Exists(baseDirectoryPath))
                return false;

            if (Directory.Exists(string.Format("{0}{1}/", baseDirectoryPath, "tables")))
            {
                File.Delete(string.Format("{0}{1}/{2}.treedb", baseDirectoryPath, "tables", tbName));
                return true;
            }
            return false;
        }

        public BST<string, object> GetTableDB(string tbName)
        {
            if (tbName != "*")
            {
                if (Directory.Exists(string.Format("{0}{1}/", baseDirectoryPath, "tables")))
                {
                    Console.WriteLine(string.Format("Database [ {0} ] are Successfully Executed  ", tbName));
                    Console.WriteLine();
                    Console.WriteLine(string.Format("Consfiguration : "));
                    return GetTable<string, object>(string.Format("{0}{1}/{2}.treedb", baseDirectoryPath, "tables", tbName));
                }
                else
                {
                    Console.WriteLine("Table Exists !");
                    return null;
                }
            }
            else
            {
                foreach (var it in GetAllTables(string.Format("{0}{1}/", baseDirectoryPath, "tables")))
                    Console.WriteLine(it);
                return null;
            }
        }

        public void FlushTable<K, V>(string path, BST<K, V> tree) where K : IComparable<K>
        {
            if (tree != null)
            {
                using (Stream s = File.Create(path))
                 (new BinaryFormatter()).Serialize(s, tree);
            }
        }

        private BST<K, V> GetTable<K, V>(string path) where K : IComparable<K>
        {
            using (Stream s = File.OpenRead(path))
                return (BST<K, V>)(new BinaryFormatter()).Deserialize(s);

        }

        private List<string> GetAllTables(string pathToTablesDirectory)
        {

            return    Directory.GetFiles(pathToTablesDirectory)
                     .Select(x => x.Substring(pathToTablesDirectory.Length, x.Length - pathToTablesDirectory.Length).Split('.')[0])
                     .ToList();
        }
    }
}
